MR与AR开发利器Unity MARS:为简洁、优雅的创作而生
我们一直在寻求一种稳定可靠的工作流。通过它,创作者们可根据自己的想法制作AR应用,让应用能够感知环境,使形式灵活多变,能够在任何平台处理任意类型的数据,更重要的是,制作时无需编写大量代码。
今年MARS发布在即,我们希望在此分享下其工作环境和应用构建的背景、方式和缘由。我们相信在下一代的体验中,此类方案将是空间和语境计算的重要一步。
如何让Unity中的AR更具实感?现实和应用的坐标很难完全对齐,开发者们需要有一款能在一个未知环境中精确定位的创作工具,它必须能适应各种不同的情景,要有“模糊”的对象放置规则。
为了解决这个问题,我们将一个完整而庞大的坐标系统拆分成了一堆小坐标系统。每个系统代表了一个空间,系统将选择不同的空间,程序化地适应现实环境。在此方案中,现实世界在定义内容的同时也定义了应用坐标系统的边界,两者可以说是共生的。
在一次Unity Labs的hackweek上,我们制作了一个包含多个位面的体验,并进行测试。多位面体验在几年前完全是不可想的,时至今日,除了MARS之外,也鲜有工具能制作出此类内容。
高效强大的功能勾起了我们创作更多、更复杂AR体验的激情雄心,但随之而来的是更多的挑战,MARS的开发过程也变成了“提问-回答、提问-回答”的不间断过程。开发的每一步都涉及了MARS功能库的开发,每一步我们都将平台的边界推得更远。
在hackweek上AR开发理念首次成型之际,我们提出了以下几个主要问题:
用数字描绘现实世界是一个极度耗费性能的构建过程,需要一个能持续增长、不停获取新数据类型的实时数据库。
游戏代码和平台的管理并不能很好地兼容,我们需要尽可能地让这些元素互不干涉。
我们希望做到即使用户不了解整个AR场景,也能编写脚本来影响场景布局。
同时我们还想将Unity的核心价值观赋予至MARS中:
与Unity类似——我们团队以“构建现实”作为口号,并为此不懈努力着。MARS将Unity拓展为一个现实体验的编辑器。
安全——空间计算是一个全新的领域,我们希望用户能在探索和实验时有更好的体验,好的开发过程应该是流畅无障碍的。
向所有开发者开放——任何MARS的功能应该能够按照开发者的技术水平要求进行调试匹配。
这些问题虽然复杂,但极具代表性。所以其解决方案不仅要全面,还需要独立于应用逻辑之外,让用户几乎感觉不到存在,最终,MARS数据层级(Data Layer)应运而生。
MARS数据层级分成四个部分:
Proxy system 代理系统 |
Query and Data Events 查询和数据事件 |
Data ownership 数据归属 |
Data Description and Storage 数据描述和存储 |
我们的出发点是用数字描述现实世界。在我们的通用AR语言中,语义是最基础的部分,而在如「floor」和「wood」这样的词形上,我们应用了最简单的语义作为其词义。
空间语义学可以构建某个事物的泛用模型,可根据现实的不同变量随之适应。以一个面为例,它可以有许多不同的形状和大小。制作一个面的AR内容涉及许多方面,包括哪面是目标面、观测的角度在哪。每个面都是不同的,但如果将这些小段数据正确放置到相应目标上,内容则可随着环境而适应。MARS(和AR)真正的强大之处在于不必使用具体的、简单的数据来制作,而可以使用更复杂的语义数据来完成。
数据归属位于层级的上方。若想让数字内容与现实世界共存,需要有一个明确的可用数据边界。数据归属能让现实自动地转换成数字内容。根据数字内容,排布出理想的现实数据对应用开发者们来说几乎是不可能的,但MARS数据层级解决了这一问题。
在AR中,Unity还有一个连贯的数据存储模式。当数据被删除、更新或数据丢失时,会触发相应的事件。而「查询和数据事件」系统则有更高级的处理方法。用户可以用数据和数值组合成查询命令。而MARS数据层级将调用诸如acquire、update、lost这类的事件,意味着用户不仅能得知是否有平面被探测,还能知道平面的具体大小、朝向和光照级别。同时MARS数据存储方式能动态地接收新自定义类型数据,意味着用户可以无视复杂程度,从任何情景中抓取事件。
MARS的数据可以为所有AR开发者所用。我们将开发者分为以下三类核心群体:
设计师:对数据的细枝末节不感兴趣,希望能在现实世界的情景和虚拟情境下制作出新的AR应用。
供应方:推出尖端的硬件和软件技术,为AR生态带来全新的数据。
工程师:熟练利用数据和互动,在设计师的蓝图和供应方的数据之间构建桥梁。
不同的群体会有不同的MARS数据库使用方法。这样一来,开发者可以有定制的体验和工作流,更高效地与其它群体互动。
1
MARS数据供应方
供应方们不必参与MARS数据层级的数据存储和描述功能。从上方图片中可以得知,MARS可以使用所有类型的外部数据和功能。供应方可以使用由几个函数构成的简单API来添加、更新或删除任何类型的数据。供应方还能添加诸如方向位、位置、旋转向、颜色、光照和粗糙度等类型的数据,将这些数据互相关联起来。
下方是AR Foundation中的平面导入到MARS中的演示:
void AddPlaneData(MRPlane plane)
{
var id = this.AddOrUpdateData(plane);
this.AddOrUpdateTrait(id, TraitNames.Plane, true);
this.AddOrUpdateTrait(id, TraitNames.Pose, plane.pose);
this.AddOrUpdateTrait(id, TraitNames.Bounds2D, plane.extents);
this.AddOrUpdateTrait(id, TraitNames.Alignment, (int)plane.alignment);
if (planeAdded != null)
planeAdded(plane);
}
需要注意的是供应方的接口使用的是一种插入式函数模式。我们可以拿掉API中的引用字段,轻易地在数据源之间切换。这一功能在创作时的数据模拟和回顾中非常重要。
static readonly TraitDefinition[] k_ProvidedTraits =
{
TraitDefinitions.Plane,
TraitDefinitions.Pose,
TraitDefinitions.Bounds2D,
TraitDefinitions.Alignment
};
在编译时有了这些数据,我们就能看到每个平台上应用可使用的数据都是哪些了。这样一来我们可以得知应用是否能运行,是否需要额外的推导API脚本来支持。
2
应用工程师
AR工程师们常常需要借助不完整或意向之外的数据描绘世界。一起来看看下面这个例子:一款能在雕像周围显示出课堂图表的应用。部分设备可以直接识别出对象,而其它设备则可以使用图片制作工具来识别对象。在其它平台上,则可以通过重新定位到预制的雕像空间来展示内容。
然而这个例子并不简单。我们再考虑些其他的情形:当一个用户查看的是雕像照片或小尺度复制品时要怎么办?那些想要尝试但没有雕像的用户该如何体验?VR用户应该如何体验?
当然,我们可以在应用中加入数据子集,用于处理所有这些情景和偶然事件。在过去此类AR体验可能是唯一的解决方案,但它并不好用。最终场景中可能会包含一张由对象和不稳定的应变方法织成的错综复杂的大网,所有应用逻辑、平台抽象语句和场景分析文本将混合在一起,时常会出现不同的平台错误,调试也十分困难。
而推导API可以解决这个问题:这些编程接口可以让工程师有相应的能力与信息来处理所有这些复杂的情形。如果没有合适的推导API可用,开发者需要明确以下事实:MARS会在脚本被调用时处理所有的逻辑。而数据提供方的特征列表会与MARS内容所需的特征列表相结合,来确定哪个API是最理想的中间媒介。
推导API接口还会与MARS的数据存储和描述功能互动。推导API可以同时访问所有MARS数据中的列表,比如整个垂直分类的平面列表。
推导API还使用相同的函数来添加、更新或删去数据,MARS可以将推导API和硬件供应方的数据匹配、混合起来,无需更改应用就能无缝衔接其函数间的沟壑。
3
设计师
我们希望将现实世界中的物品导入到Unity中,当作虚拟对象供用户参考。用户可以用虚拟对象快速创作、验证自己的数字内容。而Unity中的脚本和事件可以使用对象的引用和已有游戏代码,无需额外编程就能直接运行。这一点非常关键——我们想让MARS能无需修改,就与其它资源商店或用户的包裹兼容。我们的工作流遵循Unity的最佳实践,而多方兼容正是工作流最大的优点之一。
我们对象系统的设计十分简单,而多个简单的部件可以通过不同的方法构成复杂的结构。系统具有自足的特性,还具备所有Unity对象的功能:可以直接用在场景视图和任何类型的预制件中。
MARS内容由三个组件组成:代理体、代理组和生成器。
一个代理体代表了一个AR中的对象,这在大部分AR工具组中都是如此。而代理组则能描述那些在现实中由多个事物互相联系、相互组成的情景。迄今还没有其他的创作工具拥有这个功能。代理组的实现从算法上来说非常复杂,幸而我们已经用MARS数据层级帮你解决了。最后一个组件是生成器。生成器是包含了代理体或代理组的对象,它会复制、变换对象形成一个规则集,实现现实的改头换面。
我们来回顾下层级图表,看看整个系统是如何构成的:
所有代理体、代理组和生成器组件都是由设计师创作的,它们会生成查询命令、对事件作出反应。
我们使用查询命令在数据库中搜寻匹配数据,控制数据归属。推导API和数据供应方则能在数据库中添加、移除数据。
数据层级的每个部分都以类似的方式衔接,确保在不同的平台上能实现最佳的用户体验。
在场景中,MARS代理体对象定义了一个应用运行所需的特征集。
数据供应方定义了应用中可用的特征集。
推导API则从可用特征集中推导出运行应用所需的特征集。
推荐阅读
Unity制作人专场 | 闪耀暖暖从2D到3D的创作与进化之路
官方活动
喜欢本文,请点“在看”